/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package bikepov;

import java.awt.Color;
import java.awt.Dimension;
import java.awt.EventQueue;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Point;
import java.awt.Shape;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.InputEvent;
import java.awt.event.KeyEvent;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.awt.geom.AffineTransform;
import java.awt.geom.Arc2D;
import java.awt.geom.Path2D;
import java.awt.geom.PathIterator;
import java.awt.geom.Point2D;
import java.io.BufferedReader;
import java.io.File;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;
import java.io.PrintWriter;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import javax.swing.Box;
import javax.swing.BoxLayout;
import javax.swing.ButtonGroup;
import javax.swing.ImageIcon;
import javax.swing.JFileChooser;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JMenu;
import javax.swing.JMenuBar;
import javax.swing.JMenuItem;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.JRadioButton;
import javax.swing.JRadioButtonMenuItem;
import javax.swing.JSeparator;
import javax.swing.KeyStroke;
import javax.swing.SwingConstants;
import javax.swing.UIManager;

/**
 *
 * @author Phil Malessa
 * p.malessa1@gmail.com
 */
public class Bikepov {
    public static String VERSION = "1.0.0";
    public static Color CURRENT_COLOR = Color.RED;
    public static Color BACKGROUND_COLOR = null;
    public static int CIRCLE_COUNT = 16;
    public static int SEGMENT_COUNT = 80;
    public static int AXIS_SPACE = 300;
    public static int BOARD = 1;
    public static int COMMAND = 1;
    
    JFrame frame = new JFrame("Test");
    final TestPane pane = new TestPane();
    MenuCreator menu = new MenuCreator();
    JMenuBar menuBar;
    JMenu fileMenu, colorMenu, settingsMenu, commandMenu;
    JMenuItem newItem, openItem, saveItem;
    ButtonGroup colorGroup, boardGroup, newGroup, colornewGroup, commandGroup;
    JRadioButton rb_rgbike1, rb_rgbike2, rb_visual;
    private Map<Integer, List<Shape>> mapWheel;
    private Map<Point, Color> mapColors = new HashMap<>(CIRCLE_COUNT * SEGMENT_COUNT);
    JPanel newPanel, backgroundPanel1, backgroundPanel2, backgroundPanel3;
    
    public static void main(String[] args) {
        new Bikepov();
    }

    public Bikepov() {
        EventQueue.invokeLater(new Runnable() {
            public void run() {
                try {
                    UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
                } catch (Exception ex) {
                }
                
                
                
                frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
                frame.add(pane);
                frame.setJMenuBar(menuBar);
                frame.pack();
                frame.setLocationRelativeTo(null);
                frame.setVisible(true);
                pane.setBackground(Color.LIGHT_GRAY);
            }
        });
    }

    public class TestPane extends JPanel {


        public TestPane() {
            addMouseListener(new MouseAdapter() {
                @Override
                public void mouseClicked(MouseEvent e) {

                    Map<Integer, List<Shape>> mapWheel = getWheel();

                    for (Integer circle : mapWheel.keySet()) {
                        List<Shape> segments = mapWheel.get(circle);
                        for (int index = 0; index < segments.size(); index++) {
                            Shape segment = segments.get(index);
                            if (segment.contains(e.getPoint())) {
                                if(COMMAND == 1){ //Segments
                                    if(e.getButton() == MouseEvent.BUTTON3){ //Right Click
                                        mapColors.put(new Point(circle, index), BACKGROUND_COLOR);
                                    }else{
                                        mapColors.put(new Point(circle, index), CURRENT_COLOR);
                                    }
                                }else if(COMMAND == 2){ //Stripes
                                    if(e.getButton() == MouseEvent.BUTTON3){ //Right Click
                                        for(int index2 = 0; index2 < CIRCLE_COUNT; index2++){
                                            mapColors.put(new Point(index2, index), BACKGROUND_COLOR);
                                        }
                                    }else{
                                        for(int index2 = 0; index2 < CIRCLE_COUNT; index2++){
                                            mapColors.put(new Point(index2, index), CURRENT_COLOR);
                                        }
                                    }
                                }else if(COMMAND == 3){ //Circles
                                    if(e.getButton() == MouseEvent.BUTTON3){ //Right Click
                                        for(int index2 = 0; index2 < SEGMENT_COUNT; index2++){
                                            mapColors.put(new Point(circle, index2), BACKGROUND_COLOR);
                                        }
                                    }else{
                                        for(int index2 = 0; index2 < SEGMENT_COUNT; index2++){
                                            mapColors.put(new Point(circle, index2), CURRENT_COLOR);
                                        }
                                    }
                                }
                                repaint();
                                break;
                            }
                        }
                    }
                }
            });
            
            
            
            addMouseMotionListener(new MouseAdapter() {
                @Override
                public void mouseDragged(MouseEvent e) {
                    Map<Integer, List<Shape>> mapWheel = getWheel();
                    for (Integer circle : mapWheel.keySet()) {
                        List<Shape> segments = mapWheel.get(circle);
                        for (int index = 0; index < segments.size(); index++) {
                            Shape segment = segments.get(index);
                            if (segment.contains(e.getPoint())) {
                                if(COMMAND == 1){ //Segments
                                    if(e.getModifiersEx() == InputEvent.BUTTON3_DOWN_MASK){ //Right Click
                                        mapColors.put(new Point(circle, index), BACKGROUND_COLOR);
                                    }else{
                                        mapColors.put(new Point(circle, index), CURRENT_COLOR);
                                    }
                                }else if(COMMAND == 2){ //Stripes
                                    if(e.getModifiersEx() == InputEvent.BUTTON3_DOWN_MASK){ //Right Click
                                        for(int index2 = 0; index2 < CIRCLE_COUNT; index2++){
                                            mapColors.put(new Point(index2, index), BACKGROUND_COLOR);
                                        }
                                    }else{
                                        for(int index2 = 0; index2 < CIRCLE_COUNT; index2++){
                                            mapColors.put(new Point(index2, index), CURRENT_COLOR);
                                        }
                                    }
                                }else if(COMMAND == 3){ //Circles
                                    if(e.getModifiersEx() == InputEvent.BUTTON3_DOWN_MASK){ //Right Click
                                        for(int index2 = 0; index2 < SEGMENT_COUNT; index2++){
                                            mapColors.put(new Point(circle, index2), BACKGROUND_COLOR);
                                        }
                                    }else{
                                        for(int index2 = 0; index2 < SEGMENT_COUNT; index2++){
                                            mapColors.put(new Point(circle, index2), CURRENT_COLOR);
                                        }
                                    }
                                }
                                repaint();
                                break;
                            }
                        }
                    }
                }
            });
        }

        @Override
        public void invalidate() {
            mapWheel = null;
            super.invalidate();
        }

        protected float getRadius() {
            return Math.min(getWidth()-AXIS_SPACE, getHeight() -AXIS_SPACE);
        }

        /**
         * This builds a wheel (if required) made of segments.
         * @return 
         */
        protected Map<Integer, List<Shape>> getWheel() {
            if (mapWheel == null) {
                mapWheel = new HashMap<>(CIRCLE_COUNT);

                // The current radius
                float radius = getRadius();
                // The radius of each individual circle...
                float circleRadius = radius / CIRCLE_COUNT;
                // The range of each segment
                float extent = 360f / SEGMENT_COUNT;
                for (int circle = 0; circle < CIRCLE_COUNT; circle++) {
                    float startAngle = 0;
                    List<Shape> segments = new ArrayList<>(SEGMENT_COUNT);
                    mapWheel.put(circle, segments);

                    // Calculate the "translation" to place each segement in the
                    // center of the screen
                    float innerRadius = circleRadius * circle;
                    float x = (getWidth() - innerRadius) / 2;
                    float y = (getHeight() - innerRadius) / 2;
                    for (int seg = 0; seg < SEGMENT_COUNT; seg++) {
                        // Generate a Segment shape
                        Segment segment = new Segment(circleRadius * circle +AXIS_SPACE , circleRadius, startAngle, extent);
                        startAngle += extent;

                        // We translate the segment to the screen space
                        // This will make it faster to paint and check for mouse clicks
                        PathIterator pi = segment.getPathIterator(AffineTransform.getTranslateInstance(x - AXIS_SPACE/2, y - AXIS_SPACE/2));
                        Path2D path = new Path2D.Float();
                        path.append(pi, true);
                        segments.add(path);
                    }
                }
            }

            return mapWheel;
        }

        @Override
        protected void paintComponent(Graphics g) {
            super.paintComponent(g);

            Graphics2D g2d = (Graphics2D) g.create();

            Map<Integer, List<Shape>> mapWheel = getWheel();
            for (Integer circle : mapWheel.keySet()) {

                List<Shape> segments = mapWheel.get(circle);
                for (int index = 0; index < segments.size(); index++) {
                    Shape segment = segments.get(index);

                    Color color = mapColors.get(new Point(circle, index));
                    if (color != null) {
                        g2d.setColor(color);
                        g2d.fill(segment);    
                        
                        
                    }
                    g2d.setColor(Color.BLACK);
                    g2d.draw(segment);
                }
            }

            g2d.dispose();

        }

        @Override
        public Dimension getPreferredSize() {
            return new Dimension(800, 800);
        }
        
        public void changeColor(Color color){
            if(color == Color.RED){colorMenu.setIcon(new ImageIcon(getClass().getResource("/resources/red.png")));}
        }
    }

    public static class Segment extends Path2D.Float {

        public Segment(float radius, float thickness, float extent) {
            this(radius, thickness, 0f, extent);
        }

        public Segment(float radius, float thickness, float startAngle, float extent) {
            // Basically, we want to draw the outter edge from a to b angle,
            // draw the connecting line from the outter to the inner,
            // draw the inner from b to a angel and
            // draw the connecting line from the inner to out the outter

            // We want to span about 30 degrees, with a small gap...
            // I want the gap to be a factor of the radius

            Arc2D.Float outter = new Arc2D.Float(0, 0, radius, radius, startAngle, extent, Arc2D.OPEN);
            Arc2D.Float inner = new Arc2D.Float(thickness / 2f, thickness / 2f, radius - thickness, radius - thickness, startAngle + extent, -extent, Arc2D.OPEN);

            append(outter, true);

            float angel = startAngle + extent;
            Point2D p1 = getPointOnEdge(angel, radius);
            Point2D p2 = getPointOnEdge(angel, radius - thickness);
            // We need to adjust in for the change in the radius
            p2.setLocation(p2.getX() + (thickness / 2f), p2.getY() + (thickness / 2f));
            lineTo(p2.getX(), p2.getY());

            append(inner, true);

            angel = startAngle;
            p1 = getPointOnEdge(angel, radius);
            p2 = getPointOnEdge(angel, radius - thickness);
            p2.setLocation(p2.getX() + (thickness / 2f), p2.getY() + (thickness / 2f));
            lineTo(p1.getX(), p1.getY());

            closePath();
        }

        public Point2D getPointOnEdge(float angel, float radius) {
            angel -= 90;

            float x = radius / 2f;
            float y = radius / 2f;

            double rads = Math.toRadians((angel + 90));

            // This determins the length of tick as calculate from the center of
            // the circle.  The original code from which this derived allowed
            // for a varible length line from the center of the cirlce, we
            // actually want the opposite, so we calculate the outter limit first
            float fullLength = (radius / 2f);

            // Calculate the outter point of the line
            float xPosy = (float) (x + Math.cos(rads) * fullLength);
            float yPosy = (float) (y - Math.sin(rads) * fullLength);
            
            return new Point2D.Float(xPosy, yPosy);
        }
    }

    public class MenuCreator{
        public MenuCreator(){
            menuBar = new JMenuBar();
            fileMenu();
            colorMenu();
            settingsMenu();
            commandMenu();
        }
        public void fileMenu(){
            fileMenu = new JMenu("Datei");
            fileMenu.setMnemonic(KeyEvent.VK_D);
            menuBar.add(fileMenu);
                newItem = new JMenuItem("Neu");
                newItem.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_N, ActionEvent.CTRL_MASK));
            fileMenu.add(newItem);
                newItem.addActionListener(new ActionListener() {
                    @Override
                    public void actionPerformed(ActionEvent e) {
                           int newDialog1 = JOptionPane.showConfirmDialog( frame,"Delete image?","Warning",JOptionPane.YES_NO_OPTION);
                           if(newDialog1 == JOptionPane.YES_OPTION){
                               newPanel = new JPanel();
                               newPanel.setLayout(new BoxLayout(newPanel, BoxLayout.Y_AXIS));
                                JLabel newLabel = new JLabel("Board:");
                                rb_rgbike1 = new JRadioButton("RGBike POV 1.0");                               
                                rb_rgbike2 = new JRadioButton("RGBike POV 2.0");
                                rb_visual = new JRadioButton("VISUAL POV");
                                rb_rgbike1.setSelected(true);
                                newGroup = new ButtonGroup();
                                newGroup.add(rb_rgbike1);
                                newGroup.add(rb_rgbike2);
                                newGroup.add(rb_visual);
                               
                                JLabel backgroundLabel = new JLabel("Image Background:");
                                backgroundLabel.setHorizontalAlignment(SwingConstants.LEFT);
                                JRadioButton rb_new_red = new JRadioButton("Red");//, new ImageIcon(getClass().getResource("/resources/red.png")));
                                JRadioButton rb_new_green = new JRadioButton("Green");//,new ImageIcon(getClass().getResource("/resources/green.png")));
                                JRadioButton rb_new_blue = new JRadioButton("Blue");//,new ImageIcon(getClass().getResource("/resources/blue.png")));
                                JRadioButton rb_new_yellow = new JRadioButton("Yellow");//,new ImageIcon(getClass().getResource("/resources/yellow.png")));
                                JRadioButton rb_new_violet = new JRadioButton("Violet");//, new ImageIcon(getClass().getResource("/resources/violet.png")));
                                JRadioButton rb_new_turkis = new JRadioButton("Turkis");//, new ImageIcon(getClass().getResource("/resources/turkis.png")));
                                JRadioButton rb_new_white = new JRadioButton("White");//, new ImageIcon(getClass().getResource("/resources/white.png")));
                                JRadioButton rb_new_none = new JRadioButton("None");//, new ImageIcon(getClass().getResource("/resources/black.png")));
                                rb_new_none.setSelected(true);
                                
                                colornewGroup = new ButtonGroup();
                                colornewGroup.add(rb_new_red);
                                colornewGroup.add(rb_new_green);
                                colornewGroup.add(rb_new_blue);
                                colornewGroup.add(rb_new_yellow);
                                colornewGroup.add(rb_new_violet);
                                colornewGroup.add(rb_new_turkis);
                                colornewGroup.add(rb_new_white);
                                colornewGroup.add(rb_new_none);
                               
                               backgroundPanel2 = new JPanel();
                               backgroundPanel2.setLayout(new BoxLayout(backgroundPanel2, BoxLayout.PAGE_AXIS));
                               backgroundPanel2.add(rb_new_red);
                               backgroundPanel2.add(rb_new_green);
                               backgroundPanel2.add(rb_new_blue);
                               backgroundPanel2.add(rb_new_yellow);
                               backgroundPanel2.add(rb_new_violet);
                               backgroundPanel2.add(rb_new_turkis);
                               backgroundPanel2.add(rb_new_white);
                               backgroundPanel2.add(rb_new_none);
                               
                               
                               
                             newPanel.add(newLabel);
                             newPanel.add(new JSeparator(SwingConstants.HORIZONTAL));
                             newPanel.add(Box.createVerticalStrut(5));
                             newPanel.add(rb_rgbike1);
                             newPanel.add(rb_rgbike2);
                             newPanel.add(rb_visual);
                             newPanel.add(Box.createVerticalStrut(10));
                             newPanel.add(backgroundLabel);
                             newPanel.add(new JSeparator(SwingConstants.HORIZONTAL));
                             newPanel.add(Box.createVerticalStrut(5));
                             newPanel.add(backgroundPanel2);
                               
                             int newDialog2 = JOptionPane.showConfirmDialog(pane, newPanel, "new", JOptionPane.OK_CANCEL_OPTION);
                               
                             if(newDialog2 == JOptionPane.YES_OPTION){
                                 
                                 if(rb_rgbike1.isSelected()) {BOARD = 1; CIRCLE_COUNT = 16;}
                                 if(rb_rgbike2.isSelected()) {BOARD = 2; CIRCLE_COUNT = 24;}
                                 if(rb_visual.isSelected())  {
                                     BOARD = 3;
                                     CIRCLE_COUNT = 20; 
                                     
                                 }
                                 
                                 if(rb_new_red.isSelected()) BACKGROUND_COLOR = Color.RED;
                                 if(rb_new_green.isSelected()) BACKGROUND_COLOR = Color.GREEN;
                                 if(rb_new_blue.isSelected()) BACKGROUND_COLOR = Color.BLUE;
                                 if(rb_new_yellow.isSelected()) BACKGROUND_COLOR = Color.YELLOW;
                                 if(rb_new_violet.isSelected()) BACKGROUND_COLOR = Color.MAGENTA;
                                 if(rb_new_turkis.isSelected()) BACKGROUND_COLOR = Color.CYAN;
                                 if(rb_new_white.isSelected()) BACKGROUND_COLOR = Color.WHITE;
                                 if(rb_new_none.isSelected()) BACKGROUND_COLOR = null;                    
                                 mapColors.clear();
                                 mapWheel = null;
                                 if(BACKGROUND_COLOR != null){
                                    for (int circle = 0; circle < CIRCLE_COUNT; circle++) {
                                        for (int index = 0; index < SEGMENT_COUNT; index++) {
                                            mapColors.put(new Point(circle,index), BACKGROUND_COLOR);
                                        }
                                    }
                                 }
                               pane.repaint();
                             }

                           }
                    }});
                openItem = new JMenuItem("Öffnen");
                openItem.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_O, ActionEvent.CTRL_MASK));
            fileMenu.add(openItem);
                openItem.addActionListener(new ActionListener() {
                    @Override
                    public void actionPerformed(ActionEvent e) {
                        OpenDialog oDialog = new OpenDialog();
                    }});
                saveItem = new JMenuItem("Speichern");
                saveItem.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_S, ActionEvent.CTRL_MASK));
            fileMenu.add(saveItem);
                saveItem.addActionListener(new ActionListener() {
                    @Override
                    public void actionPerformed(ActionEvent e) {
                        SaveDialog sDialog = new SaveDialog();
                    }});
        }
        public void colorMenu(){
            colorMenu = new JMenu("Color");
            colorMenu.setMnemonic(KeyEvent.VK_F);
            colorMenu.setIcon(new ImageIcon(getClass().getResource("/resources/red.png")));
            menuBar.add(colorMenu);
                colorGroup = new ButtonGroup();
                JRadioButtonMenuItem rbRed = new JRadioButtonMenuItem("Red", new ImageIcon(getClass().getResource("/resources/red.png")));
                JRadioButtonMenuItem rbGreen = new JRadioButtonMenuItem("Green", new ImageIcon(getClass().getResource("/resources/green.png")));
                JRadioButtonMenuItem rbBlue = new JRadioButtonMenuItem("Blue", new ImageIcon(getClass().getResource("/resources/blue.png")));
                JRadioButtonMenuItem rbYellow = new JRadioButtonMenuItem("Yellow", new ImageIcon(getClass().getResource("/resources/yellow.png")));
                JRadioButtonMenuItem rbViolet = new JRadioButtonMenuItem("Violet", new ImageIcon(getClass().getResource("/resources/violet.png")));
                JRadioButtonMenuItem rbTurkis = new JRadioButtonMenuItem("Turkis", new ImageIcon(getClass().getResource("/resources/turkis.png")));
                JRadioButtonMenuItem rbWhite = new JRadioButtonMenuItem("White", new ImageIcon(getClass().getResource("/resources/white.png")));
                JRadioButtonMenuItem rbNone = new JRadioButtonMenuItem("None", new ImageIcon(getClass().getResource("/resources/black.png")));
                rbRed.setAccelerator(KeyStroke.getKeyStroke('1'));
                rbGreen.setAccelerator(KeyStroke.getKeyStroke('2'));
                rbBlue.setAccelerator(KeyStroke.getKeyStroke('3'));
                rbYellow.setAccelerator(KeyStroke.getKeyStroke('4'));
                rbViolet.setAccelerator(KeyStroke.getKeyStroke('5'));
                rbTurkis.setAccelerator(KeyStroke.getKeyStroke('6'));
                rbWhite.setAccelerator(KeyStroke.getKeyStroke('7'));
                rbNone.setAccelerator(KeyStroke.getKeyStroke('8'));
                rbRed.setSelected(true);
                colorGroup.add(rbRed);
                colorGroup.add(rbGreen);
                colorGroup.add(rbBlue);
                colorGroup.add(rbYellow);
                colorGroup.add(rbViolet);
                colorGroup.add(rbTurkis);
                colorGroup.add(rbWhite);
                colorGroup.add(rbNone);
            colorMenu.add(rbRed);
            colorMenu.add(rbGreen);
            colorMenu.add(rbBlue);
            colorMenu.add(rbYellow);
            colorMenu.add(rbViolet);
            colorMenu.add(rbTurkis);
            colorMenu.add(rbWhite);
            colorMenu.add(rbNone);
                rbRed.addActionListener(new ActionListener() {
                    @Override
                    public void actionPerformed(ActionEvent e) {CURRENT_COLOR = Color.RED; colorMenu.setIcon(new ImageIcon(getClass().getResource("/resources/red.png")));}});
                rbGreen.addActionListener(new ActionListener() {
                    @Override
                    public void actionPerformed(ActionEvent e) {CURRENT_COLOR = Color.GREEN; colorMenu.setIcon(new ImageIcon(getClass().getResource("/resources/green.png")));}});
                rbBlue.addActionListener(new ActionListener() {
                    @Override
                    public void actionPerformed(ActionEvent e) {CURRENT_COLOR = Color.BLUE; colorMenu.setIcon(new ImageIcon(getClass().getResource("/resources/blue.png")));}});
                rbYellow.addActionListener(new ActionListener() {
                    @Override
                    public void actionPerformed(ActionEvent e) {CURRENT_COLOR = Color.YELLOW; colorMenu.setIcon(new ImageIcon(getClass().getResource("/resources/yellow.png")));}});
                rbViolet.addActionListener(new ActionListener() {
                    @Override
                    public void actionPerformed(ActionEvent e) {CURRENT_COLOR = Color.MAGENTA; colorMenu.setIcon(new ImageIcon(getClass().getResource("/resources/violet.png")));}});
                rbTurkis.addActionListener(new ActionListener() {
                    @Override
                    public void actionPerformed(ActionEvent e) {CURRENT_COLOR = Color.CYAN; colorMenu.setIcon(new ImageIcon(getClass().getResource("/resources/turkis.png")));}});
                rbWhite.addActionListener(new ActionListener() {
                    @Override
                    public void actionPerformed(ActionEvent e) {CURRENT_COLOR = Color.WHITE; colorMenu.setIcon(new ImageIcon(getClass().getResource("/resources/white.png")));}});
                rbNone.addActionListener(new ActionListener() {
                    @Override
                    public void actionPerformed(ActionEvent e) {CURRENT_COLOR = null; colorMenu.setIcon(new ImageIcon(getClass().getResource("/resources/black.png")));}});
        }
        public void settingsMenu(){
            settingsMenu = new JMenu("Settings");
            settingsMenu.setMnemonic(KeyEvent.VK_S);
            menuBar.add(settingsMenu);
                boardGroup = new ButtonGroup();
                JRadioButtonMenuItem rb_b1 = new JRadioButtonMenuItem("RGBike POV 1.0");
                JRadioButtonMenuItem rb_b2 = new JRadioButtonMenuItem("RGBike POV 2.0");
                JRadioButtonMenuItem rb_b3 = new JRadioButtonMenuItem("VISUAL POV");
                rb_b1.setSelected(true);
                boardGroup.add(rb_b1);
                boardGroup.add(rb_b2);
                boardGroup.add(rb_b3);
            settingsMenu.add(new JLabel("Board: "));
            settingsMenu.add(new JSeparator(SwingConstants.HORIZONTAL));
            settingsMenu.add(rb_b1);
            settingsMenu.add(rb_b2);
            settingsMenu.add(rb_b3);
                rb_b1.addActionListener(new ActionListener() {
                    @Override
                    public void actionPerformed(ActionEvent e) {
                        BOARD = 1; CIRCLE_COUNT = 16; mapWheel = null; pane.repaint();}});
                rb_b2.addActionListener(new ActionListener() {
                    @Override
                    public void actionPerformed(ActionEvent e) {
                        BOARD = 2; CIRCLE_COUNT = 24; mapWheel = null; pane.repaint();}});
                rb_b3.addActionListener(new ActionListener() {
                    @Override
                    public void actionPerformed(ActionEvent e) {
                        BOARD = 3; CIRCLE_COUNT = 20; mapWheel = null; pane.repaint();}});
        }
        public void commandMenu(){
            commandMenu = new JMenu("Commands");
            commandMenu.setMnemonic(KeyEvent.VK_C);
            menuBar.add(commandMenu);
                commandGroup = new ButtonGroup();
                JRadioButtonMenuItem rb_segment = new JRadioButtonMenuItem("Segment");
                JRadioButtonMenuItem rb_stripe = new JRadioButtonMenuItem("Stripe");
                JRadioButtonMenuItem rb_circle = new JRadioButtonMenuItem("Circle");
                rb_segment.setSelected(true);
                commandGroup.add(rb_segment);
                commandGroup.add(rb_stripe);
                commandGroup.add(rb_circle);
            commandMenu.add(rb_segment);
            commandMenu.add(rb_stripe);
            commandMenu.add(rb_circle);
                rb_segment.addActionListener(new ActionListener() {
                    @Override
                    public void actionPerformed(ActionEvent e) {
                        COMMAND = 1;}});
                rb_stripe.addActionListener(new ActionListener() {
                    @Override
                    public void actionPerformed(ActionEvent e) {
                        COMMAND = 2;}});
                rb_circle.addActionListener(new ActionListener() {
                    @Override
                    public void actionPerformed(ActionEvent e) {
                        COMMAND = 3;}});
        }
    }
    
    public class OpenDialog {
        public OpenDialog(){
            JFileChooser fc = new JFileChooser();
            // Show open dialog; this method does not return until the dialog is closed
            int returnVal = fc.showOpenDialog(frame);
            if(returnVal == JFileChooser.APPROVE_OPTION){
                mapColors.clear();
                mapWheel = null;
                File openFile = fc.getSelectedFile();
                String dataBuffer;
                int readIndex = 0;
                int mapIndex = 0;
                char charBuffer = 0;
                System.out.println("Opening: "+ openFile.getName());
                try{
                    BufferedReader bReader = new BufferedReader(new FileReader(openFile));
                    do{
                       dataBuffer = bReader.readLine();
                    }while(!dataBuffer.contains("pic["));
                    if(dataBuffer.contains("pic[80][16]")){ BOARD = 1; CIRCLE_COUNT = 16; SEGMENT_COUNT = 80;}
                    if(dataBuffer.contains("pic[80][24]")){ BOARD = 2; CIRCLE_COUNT = 24; SEGMENT_COUNT = 80;}
                    if(dataBuffer.contains("pic[80][20]")){ BOARD = 3; CIRCLE_COUNT = 20; SEGMENT_COUNT = 80;}
                    do{
                       dataBuffer = bReader.readLine();
                    }while(!dataBuffer.contains("//START"));
                    System.out.println(dataBuffer.length());
                    for(int seg = 0; seg < SEGMENT_COUNT; seg++){
                        //System.out.println(seg);
                        dataBuffer = bReader.readLine();
                        mapIndex = CIRCLE_COUNT-1;
                        for(int j = 0;j < dataBuffer.length(); j++){
                            charBuffer = dataBuffer.charAt(j);
                            switch(charBuffer){
                                case '4': {mapColors.put(new Point(mapIndex, seg), Color.RED); mapIndex--; break;}
                                case '2': {mapColors.put(new Point(mapIndex, seg), Color.GREEN);mapIndex--;break;}
                                case '1': {mapColors.put(new Point(mapIndex, seg), Color.BLUE);mapIndex--;break;}
                                case '6': {mapColors.put(new Point(mapIndex, seg), Color.YELLOW);mapIndex--;break;}
                                case '5': {mapColors.put(new Point(mapIndex, seg), Color.MAGENTA);mapIndex--;break;}
                                case '3': {mapColors.put(new Point(mapIndex, seg), Color.CYAN);mapIndex--;break;}
                                case '7': {mapColors.put(new Point(mapIndex, seg), Color.WHITE);mapIndex--;break;}
                                case '0': {mapColors.put(new Point(mapIndex, seg), null);mapIndex--;break;}
                            }
                        }
                        dataBuffer = bReader.readLine();
                        mapIndex = dataBuffer.length();
                        for(int j = 0;j < dataBuffer.length(); j++){
                            charBuffer = dataBuffer.charAt(j);
                            switch(charBuffer){
                                case '4': {mapColors.put(new Point(mapIndex, seg), Color.RED); mapIndex--; break;}
                                case '2': {mapColors.put(new Point(mapIndex, seg), Color.GREEN);mapIndex--;break;}
                                case '1': {mapColors.put(new Point(mapIndex, seg), Color.BLUE);mapIndex--;break;}
                                case '6': {mapColors.put(new Point(mapIndex, seg), Color.YELLOW);mapIndex--;break;}
                                case '5': {mapColors.put(new Point(mapIndex, seg), Color.MAGENTA);mapIndex--;break;}
                                case '3': {mapColors.put(new Point(mapIndex, seg), Color.CYAN);mapIndex--;break;}
                                case '7': {mapColors.put(new Point(mapIndex, seg), Color.WHITE);mapIndex--;break;}
                                case '0': {mapColors.put(new Point(mapIndex, seg), null);mapIndex--;break;}
                            }
                        }
                    }
                pane.repaint();
                }catch(IOException ioe){
                    ioe.printStackTrace();
                }
            }
    }
    }
    
    
    public class SaveDialog {
        public SaveDialog(){
            JFileChooser fc = new JFileChooser();
            // Show open dialog; this method does not return until the dialog is closed
            int returnVal = fc.showSaveDialog(pane);
            if (returnVal == JFileChooser.APPROVE_OPTION){
                File saveFile = fc.getSelectedFile();
                System.out.print("Saving: "+ saveFile.getName());
                try{
                    PrintWriter pWriter = new PrintWriter(new FileWriter(saveFile), true);
                    pWriter.print("//BikePOV Image created for ");
                    switch(BOARD){
                        case 1:pWriter.print("RGBike POV 1.0\n");break;
                        case 2:pWriter.print("RGBike POV 2.0\n");break;
                        case 3:pWriter.print("VISUAL POV\n");break;}
                    pWriter.print("//Build Date: "+ new java.util.Date()+"\n");
                    pWriter.print("//BikePOV Version "+VERSION+"\n\n");
                    pWriter.print("uint8_t pic["+SEGMENT_COUNT+"]["+CIRCLE_COUNT+"] ={\n"); //init line
                    pWriter.print("//START\n");
                    for(int segmentIndex = 0; segmentIndex < SEGMENT_COUNT; segmentIndex++){
                        pWriter.print("{");
                        for( int circleIndex = CIRCLE_COUNT; circleIndex > 0; circleIndex--){
                            Color saveColor = mapColors.get(new Point(circleIndex-1,segmentIndex));
                            if(saveColor == Color.RED)pWriter.print("4");
                            else if(saveColor == Color.GREEN)pWriter.print("2");
                            else if(saveColor == Color.BLUE)pWriter.print("1");
                            else if(saveColor == Color.YELLOW)pWriter.print("6");
                            else if(saveColor == Color.CYAN)pWriter.print("5");
                            else if(saveColor == Color.MAGENTA)pWriter.print("3");
                            else if(saveColor == Color.WHITE)pWriter.print("7");
                            else if(saveColor == null)pWriter.print("0");
                            if(circleIndex > 1)pWriter.print(",");
                        }
                        pWriter.print("}");
                        if(segmentIndex < (SEGMENT_COUNT-1))pWriter.print(",\n");
                        
                    }
                    pWriter.print("};");
                    
                    pWriter.flush();
                    pWriter.close();
                }catch(IOException ioe){
                    ioe.printStackTrace();
                }
            }
    }
    }

}
